package com.itlong.cloud.intercept;

import com.itlong.cloud.POJO.VO.MessageVO;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.enumerate.CloudDeviceErrorCodeEnum;
import com.itlong.cloud.enumerate.CloudElevatorEncryptTypeEnum;
import com.itlong.cloud.enumerate.PropertyEquipTypeEnum;
import com.itlong.cloud.enumerate.ecode.BaseErrorCodeEnum;
import com.itlong.cloud.equip.commons.ICloudElevatorServiceClient;
import com.itlong.cloud.equip.commons.ICloudEntranceServiceClient;
import com.itlong.cloud.equip.property.ICloudIntercomServiceClient;
import com.itlong.cloud.equip.property.IDeviceCloudControllerServiceClient;
import com.itlong.cloud.utils.encrypt.DesEncryptUtil;
import com.itlong.cloud.utils.encrypt.Md5EncryptUtil;
import com.itlong.cloud.utils.node.JsonUtil;
import com.itlong.cloud.utils.words.StringHandlerUtil;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;

/**
 *
 */
@Aspect
@Component
public class LoginIntercept {
    private static final Logger LOG = LoggerFactory.getLogger(LoginIntercept.class);
 // 定义一个切入点
    @Pointcut("execution(* com.itlong.cloud.controller..*.*(..)) && !@annotation(com.itlong.cloud.annotation.UnAuthAccessRequired) && !@annotation(com.itlong.cloud.annotation.UnParamEncrypt)")
    public void excudeService(){}

    @Value("${"+ PlatformConstants.CLOUD_TALK_TOKEN_DONTINTERCEPT+"}")
    String dontIntercept;

    @Value("${" + PlatformConstants.CLOUD_ELEVATOR_AESKEY + "}")
    private  String cloudElevatorAeskey; //AES加密KEY
    @Value("${" + PlatformConstants.CLOUD_ELEVATOR_MD5KEY + "}")
    private  String cloudElevatorMd5key;  //MD5加密KEY

    @Autowired
    ICloudIntercomServiceClient iCloudIntercomServiceClient;

    @Autowired
    ICloudElevatorServiceClient iCloudElevatorServiceClient;

    @Autowired
    ICloudEntranceServiceClient iCloudEntranceServiceClient;

    @Autowired
    IDeviceCloudControllerServiceClient iDeviceCloudControllerServiceClient;

    @Around("excudeService()")
    public Object twiceAsOld(ProceedingJoinPoint thisJoinPoint) throws Throwable{
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        //设备端会话token请求拦截
        String[] interceptMethod= StringHandlerUtil.splitString(dontIntercept);
        String uri = request.getRequestURI();
//        LOG.info (String.format("请求路由:%s，客户端地址：%s", uri, HttpProtocolUtil.getIpAddr(request)));
        if (uri.indexOf("error") > -1 || uri.indexOf("404") > -1) {   //屏蔽错误中继续错误的死循环
            return thisJoinPoint.proceed();
        }
        //获取拦截方法的所有属性
        MethodSignature signature = (MethodSignature) thisJoinPoint.getSignature();
        //循环配置不需要拦截的方法
        for (String method: interceptMethod){
            if (signature.getMethod().getName().equals(method)){
                return thisJoinPoint.proceed();
            }
        }
        //拿到token
        String token=null;
        //设备类型
        String deviceType=null;
        //获取所有的请求参数键值对并根据加密方案进行校验通信加密是否正常
        Map map = request.getParameterMap();
        int encryptionAbility = 0; //默认未采用加密方案
        if (map.containsKey("encryptionAbility")&&StringUtils.isNotBlank(request.getParameter("encryptionAbility"))){
            encryptionAbility = Integer.parseInt(request.getParameter("encryptionAbility"));
        }
        if (encryptionAbility != CloudElevatorEncryptTypeEnum.NOT_SUPPORT.getEncryptType()&&encryptionAbility != CloudElevatorEncryptTypeEnum.HTTPS_ENCRYPT.getEncryptType()){
            String encrypScript = "";
            if (map.containsKey("encrypScript")){   //是否携带加密串，检测预防异常
                encrypScript = request.getParameter("encrypScript").toString();
            }
            if (StringUtils.isBlank(encrypScript)){ //加密串未携带，参数异常
                return getEncryptResult(new MessageVO(BaseErrorCodeEnum.PARAM_ERR.getErrorCode()),encryptionAbility);
            }else {
                //验证MD5是否正确
                String content=StringHandlerUtil.replaceBlank(encrypScript.substring(0, encrypScript.length() - 32));
//                System.out.println(content);
                String md5=encrypScript.substring(encrypScript.length() - 32, encrypScript.length());
              // System.out.println("md5====>"+md5);
                String emd5=Md5EncryptUtil.md5(content + cloudElevatorMd5key).toUpperCase();
               //System.out.println(content + cloudElevatorMd5key);
                if(!Md5EncryptUtil.md5(content + cloudElevatorMd5key).toUpperCase().equals(md5)){
                    return getEncryptResult(new MessageVO(CloudDeviceErrorCodeEnum.CLOUD_ELEVATOR_ILLEGAL_REQUEST.getErrorCode()),encryptionAbility);
                }
                //解密
                String encryptResult = URLDecoder.decode(DesEncryptUtil.aesDecrypt(content, cloudElevatorAeskey).replaceAll("%0A",""), "UTF-8");

                Map<String,Object> params = JsonUtil.toObject(encryptResult,HashMap.class);
                try {
                    token = StringHandlerUtil.getNullOrStringForObject(params.get("token"));
                    deviceType = StringHandlerUtil.getNullOrStringForObject(params.get("deviceType"));
                    request.setAttribute("params", params);
                }catch (Exception e){
                    return getEncryptResult(new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode()),encryptionAbility);
                }
            }
        }else{
           token = request.getParameter("token");
           deviceType = request.getParameter("deviceType");
        }

        if (StringUtils.isBlank(token)){
            if (encryptionAbility != CloudElevatorEncryptTypeEnum.NOT_SUPPORT.getEncryptType()&&encryptionAbility != CloudElevatorEncryptTypeEnum.HTTPS_ENCRYPT.getEncryptType()) {
                return getEncryptResult(new MessageVO(CloudDeviceErrorCodeEnum.CLOUD_TTOKEN_IS_NULL.getErrorCode()),encryptionAbility);
            }else{
                return new MessageVO(CloudDeviceErrorCodeEnum.CLOUD_TTOKEN_IS_NULL.getErrorCode());
            }
        }else {
            deviceType = (StringUtils.isNotBlank(deviceType) && deviceType.equals("21") ?
                    StringHandlerUtil.strToIntDef(deviceType,99,16)+"" : deviceType);
            Object cacheVO;
            if(StringUtils.isBlank(deviceType)) {
                //解密token拿到云对讲设备信息
                cacheVO = iCloudIntercomServiceClient.retrieve(token);
            }else if (PropertyEquipTypeEnum.CLOUD_ELEVATOR_DEVICE_TYPE.getType()==Integer.parseInt(deviceType)){
                cacheVO = iCloudElevatorServiceClient.retrieve(token);
            }else if (PropertyEquipTypeEnum.CLOUD_ENTRANCE.getType()==Integer.parseInt(deviceType) || PropertyEquipTypeEnum.CLOUD_WIPPEN_DEVICE_TYPE.getType()==Integer.parseInt(deviceType)
                    || PropertyEquipTypeEnum.CLOUD_UNIBODY_FACE_DEVICE.getType()==Integer.parseInt(deviceType)
                    || PropertyEquipTypeEnum.HARDWARE_CLOUD_UNIBODY_ENTRANCE_DEVICE.getType()==Integer.parseInt(deviceType)) {
                cacheVO = iCloudEntranceServiceClient.retrieve(token);
            }else if(PropertyEquipTypeEnum.CLOUD_ELEVATOR_CLUSTER_CONTROLLER.getType()==Integer.parseInt(deviceType)) {
                cacheVO = iDeviceCloudControllerServiceClient.retrieve(token);
            } else{
                cacheVO=null;
            }
            if (null == cacheVO){
                if (encryptionAbility != CloudElevatorEncryptTypeEnum.NOT_SUPPORT.getEncryptType()&&encryptionAbility != CloudElevatorEncryptTypeEnum.HTTPS_ENCRYPT.getEncryptType()){
                    return getEncryptResult(new MessageVO(CloudDeviceErrorCodeEnum.CLOUD_LOGIN_ERROE.getErrorCode()),encryptionAbility);
                }else {
                    return new MessageVO(CloudDeviceErrorCodeEnum.CLOUD_LOGIN_ERROE.getErrorCode());
                }
            }else {
                Object result = thisJoinPoint.proceed();
                if (encryptionAbility != CloudElevatorEncryptTypeEnum.NOT_SUPPORT.getEncryptType()&&encryptionAbility != CloudElevatorEncryptTypeEnum.HTTPS_ENCRYPT.getEncryptType()){
                    //加密
                    MessageVO messageVO = (MessageVO)result;
                    String encryptResult = DesEncryptUtil.aesEncrypt(JsonUtil.toJSON(messageVO),cloudElevatorAeskey,cloudElevatorMd5key);
                    Map<String,Object> resultMap = new HashMap<>();
                    resultMap.put("encryptionAbility",encryptionAbility); //加密方案需要参与响应结果加密
                    resultMap.put("encrypScript", encryptResult);
                    return resultMap;
                }
                return result;
            }
        }
    }

    /**
     * <desc>
     *      返回加密内容
     * </desc>
     *
     * @return
     * @author Jiaqi.X
     * @createDate 2018/04/10
     */
    private Map<String,Object> getEncryptResult(Object result,Integer encryptionAbility) throws Exception {
        MessageVO messageVO = (MessageVO)result;
        String encryptResult = DesEncryptUtil.aesEncrypt(JsonUtil.toJSON(messageVO),cloudElevatorAeskey,cloudElevatorMd5key);
        Map<String,Object> resultMap = new HashMap<>();
        resultMap.put("encryptionAbility",encryptionAbility); //加密方案需要参与响应结果加密
        resultMap.put("encrypScript", encryptResult);
        return resultMap;
    }

    public static void main(String[] args) throws Exception {
        String a = "dzgPV/cZybUNGTkYHYivmdp8nVzJQwhJdhiK7LcxCujEsAetTFb5/EfVYGQLYeMdBq9Z6u2FOL5d/LTaSbolL3C0y6FsH8r04h/O0g11GRTYJ9KQUmapFblB+zporQHq6taiaR2oneC01hKdA4ROMF34JpQU26jehjLQd/un3t5zkAhWqgxTVuBV0c1AtWYYAouMHyCwUW4vsZD9rGfDuX9V26+KGzD3AqhyxbygdxJUrdOIUh53q7B6cTFibBkMi/mOS7cmmTd8gRdJsjopPGkSUUKGeHvr2zDkVwhZFgIN8v/KDFk+Kk8XC1ytQIN2w+hmIPbA2XxTdUhE8kaca1MgwsT3NuK6iioIpOW8NMe2r9Rl7RrMT08l+NXR66eikiYVKAHuj/h4HN5+8ZVpbBt7sSci7yk1RroAKOlcKp9zq5ObOzKc6lkSOWZQQxhhl+1lVksB3SUWvHuB6F4R8JGUNBCsAxOE/Nl/W5xcwa4AIyj0S5hmRac1fdrgwhcddl65PfUUk37ukKNqgzoKn15wZoqkEGhqRmti4hxjM544LzFRScfs4f3Eo52XN50zBUaZJilpt5YQ3yDvmDtdM3q0qqdOtIW3SFX18fzwzYC3FQGjY+3nFXY3XzNRiakJfOEqPcF/dqvq2X3/fVndAjY0NKFyEfR2kvluZXmf2snKIzCMTS4ZyLyBzYW5nvondtsnj9sSvoUwsu2ULCyLBJWm1u1cobWsEAh0Kb7B2whtZwt3cAVrtzbBGrouTMRuQSoyPf8dcqpBYNvP/4HgxgLfcaim01hR1w2yk+skaiPXWMHjRHNqhOYHmJgkicPBfL1Za3MwAFGj15kW0Td5zUl+ZPr0JOWKSBqWHznaE/iCupZI2yU9277zLpGlCzb3sfEI5vd8P0WxiGDDBvoGe4+FZZbabllKUt9mBlZBc85Bx5YfnTpOApFizuVucztr1ha8lESNDrgDM9DXWyN/haFQNQ+EHOLz93Sh41gXjBfyCeYbAdAzXI84d48/EcuoeGfalK7PFG09+n8Pb994/HQbhz40ZsMtaPu8F5Bui04dfoIrMQKMy0wLeNYFQ7PWe4dpYyvhGfJVHGOfRR4EN2I3B1DsKQoNFYAmztT8sTHhq6gxlRc/vYEpTGLFSkjgcj70/gT7lUEnPfKS+p7T6T+IqE5syR96bN2/u9lPWt3RMVxbt3Xraw8M7A69QWCdiKr98AtSdTMAfilpGdQHcGREwRXJlPOgVp94OKbzKHNEZd4QjCSbGHq6Ysw+VzGCOxOmqIwIRMh8rMIWiJ5dE+O6m3OR6AZXFEXAKYu585PIG7w67HOn7h/qUS7oUCrVj0g/rEog+fLHkDUEZlF5LjdX3mcrtNhvFupVcrMcGYiVA9mmKHxd7taEUk/9CJyXs6ky9odkKFEfaZhfg3fE1VUGa6Vg07FKClQYKTLkZ2NonhYM+KUye9P057GyRgw7bvDLrVanaNMfFysEejAKXmB9KHYT3p1dVEKZZulVFMvjPG0mduXEVK3pg/e+W8mF5n8VNCoBXWKbIxJkIl5QkZx8t+2m2xlw8o09O4ujGug2+oUOGC9MzxX007UlOinSS2EhxI7c6ejRE6/xrfDst9J48HsvbeEEbTlzdFa+bZ/mtSjCKgo02D7zwIJC1egKjCnnnNeBbG7jHuI6xTjA/PPFfSd89SHhF9wCYepV6GkaVkKW75G1Q2jPsnD42bqZHUXHLnExiluV1BloAbMcEnQ1I7sNborVbCSTh9Sj7rDlM2WCvANY9UpOMafBxYuQieVeJFAiFJGgG3U/1qubLAuSFhueUm";
        String content=StringHandlerUtil.replaceBlank(a.substring(0, a.length() - 32));
        //解密
        String encryptResult = URLDecoder.decode(DesEncryptUtil.aesDecrypt(content, "1234567890123456"), "UTF-8");
        System.out.println(encryptResult);
    }


}
